package com.exam.schedule;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.exam.common.Utils.DateUtil;
import com.exam.common.Utils.EmailUtils2;
import com.exam.common.Utils.IDGenerator;
import com.exam.common.enums.impl.ExamStatusEnum;
import com.exam.common.enums.impl.ExamUserStatusEnum;
import com.exam.common.enums.impl.InfoTypeEnum;
import com.exam.dao.ExamDao;
import com.exam.dao.ExamUserDao;
import com.exam.dao.InfoDao;
import com.exam.dao.UserDao;
import com.exam.pojo.entity.Exam;
import com.exam.pojo.entity.ExamUser;
import com.exam.pojo.entity.Info;
import com.exam.pojo.model.ExamModel;
import com.exam.pojo.model.ExamUserModel;
import com.exam.pojo.param.ExamParam;
import com.exam.pojo.param.InfoParam;
import com.exam.pojo.param.remind;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import org.apache.commons.mail.EmailException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description 定时任务
 * @Date 2023/2/21
 * @Author ChengKe
 */

@Component
@RequiredArgsConstructor
public class ExamInfoPublishXxjob {

    private final EmailUtils2 emailUtils2;
    private final ExamUserDao examUserDao;
    private final UserDao userDao;
    private final ExamDao examDao;
    private final InfoDao infoDao;

    /**
     * 发布报名信息任务
     */
    @XxlJob("RegistrationInformation")
    public void RegistrationInformation() {
        ExamParam examParam = new ExamParam();
        List<ExamModel> examModel =  examDao.queryAllByLimit(examParam);
        examModel.forEach(item->{
            long currentTimeMillis = DateUtil.getCurrentTimeMillis();
            // 报名考试时间 <=当前时间 <= 报名结束时间
            if (item.getApplyStartTime() <= currentTimeMillis && item.getApplyEndTime() >= currentTimeMillis){
                this.update(item,InfoTypeEnum.Registration_Time_Announcement,ExamStatusEnum.Start,examParam);
            }
        });
    }

    /**
     * 发布打印准考证信息
     */
    @XxlJob("PintInformation")
    public void  PintInformation(){
        long currentTimeMillis = DateUtil.getCurrentTimeMillis();
        ExamParam examParam = new ExamParam();
        List<ExamModel> examModels = examDao.queryAllByLimit(examParam);
        examModels.forEach(item->{
            // 报名结束时间 <= 当前时间 <= 考试开始时间
            if (item.getApplyEndTime() <= currentTimeMillis && item.getStartTime() >= currentTimeMillis) {
                this.update(item,InfoTypeEnum.Notice_of_Examination_Time,ExamStatusEnum.Stop,examParam);
            }
        });
    }

    /**
     * 发布成绩查询信息
     */
    @XxlJob("ResultsQueryInformation")
    public void ResultsQueryInformation(){
        long currentTimeMillis = DateUtil.getCurrentTimeMillis();
        ExamParam examParam = new ExamParam();
        List<ExamModel> examModels = examDao.queryAllByLimit(examParam);
        examModels.forEach(item->{
            // 考试结束时间 <= 当前时间
            if (item.getEndTime() <= currentTimeMillis){
                this.update(item,InfoTypeEnum.Examination_Announcement,ExamStatusEnum.Score_Inquiry,examParam);
            }
        });
    }



    /**
     * 提醒用户考试
     */
    @XxlJob("RemindExamUser")
    private void RemindExamUser(){
        // todo
        // 比当前时间早半个小时的时间
        Long end = Instant.now().minusSeconds(1800).toEpochMilli();
        // 比当前时间早1个小时的时间
        Long start = Instant.now().minus(Duration.ofHours(1)).toEpochMilli();
        List<remind> reminds = examUserDao.selectByStatus();
      reminds.forEach(item->{
          if (item.getStartTime()<= end && item.getStartTime()>=start ){
              try {
                  emailUtils2.sendMsg(item.getUserId(),item.getTitle(),"有风雨是常态，风雨兼程是状态，风雨无阻是心态，距离考试开始不足一个小时，请大家迅速赶往考场，在此祝福大家考试顺利，");
              } catch (EmailException e) {
                  e.printStackTrace();
              }
          }
      });
    }


    /**
     * 根据当前时间所处位置设置对应的考试状态 插入Info表
     */
    @Transactional
    public void update(ExamModel item,InfoTypeEnum e,ExamStatusEnum x,ExamParam examParam){
        InfoParam infoParam = new InfoParam();
        // 主键id
        infoParam.setId(IDGenerator.StringID());
        // 设置公告信息的考试名称
        infoParam.setTitle(item.getTitle());
        // 介绍
        infoParam.setContent(item.getDescription());
        // 考试id
        infoParam.setExamId(item.getId());
        // 设置公告的类型
        infoParam.setType(e);
        // 设置考试的状态
        examParam.setStatus(x);
        // 设置考试的id
        examParam.setId(item.getId());
        // 保存到数据库
        examDao.update(examParam);
        // 查询是否存在 不存在则插入
        Info info = infoDao.selectByExamIdAndType(item.getId(), InfoTypeEnum.Notice_of_Examination_Time.getCode());
        if (info == null) {
            infoParam.setCreateTime(DateUtil.getCurrentTimeMillis());
            infoDao.insert(infoParam);
        }
    }

}
